package io.itit.ecp.admin.file.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import io.itit.ecp.admin.file.AliOssProperties;
import io.itit.ecp.admin.file.FileUploadResult;
import io.itit.ecp.admin.file.service.FileService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;


@RequiredArgsConstructor
public class AliOssFileServiceImpl implements FileService, DisposableBean {

    private final AliOssProperties ossProperties;

    private final OSS ossClient;

    @Override
    public FileUploadResult upload(MultipartFile multipartFile) throws IOException {
        return this.upload(ossProperties.getBucketName(), multipartFile);
    }

    private String getBaseDir() {
        return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
    }

    @Override
    public FileUploadResult upload(String bucketName, MultipartFile multipartFile) throws IOException {
        String fileName = getBaseDir() + "/" + FileService.generatorKey(multipartFile.getOriginalFilename());
        PutObjectRequest putRequest = new PutObjectRequest(bucketName, fileName, multipartFile.getInputStream());
        try {
            ossClient.putObject(putRequest);
            return new FileUploadResult()
                    .setBucketName(bucketName)
                    .setOriginalFilename(multipartFile.getOriginalFilename())
                    .setContentType(multipartFile.getContentType())
                    .setUrl(ossProperties.getDomain() + "/" + fileName)
                    .setUploadPath(fileName);
        } catch (OSSException | ClientException e) {
            throw new IOException(e);
        }
    }

    @Override
    public FileUploadResult upload(byte[] bytes, String fileName, String contentType) throws IOException {
        return this.upload(ossProperties.getBucketName(), bytes, fileName, contentType);
    }

    @Override
    public FileUploadResult upload(String bucketName, byte[] bytes, String fileName, String contentType) throws IOException {
        String newFileName = getBaseDir() + "/" + FileService.generatorKey(fileName);
        PutObjectRequest putRequest = new PutObjectRequest(bucketName, fileName, new ByteArrayInputStream(bytes));
        try {
            ossClient.putObject(putRequest);
            return new FileUploadResult()
                    .setBucketName(bucketName)
                    .setOriginalFilename(fileName)
                    .setContentType(contentType)
                    .setUrl(ossProperties.getDomain() + "/" + newFileName)
                    .setUploadPath(newFileName);
        } catch (OSSException | ClientException e) {
            throw new IOException(e);
        }
    }

    @Override
    public void destroy() throws Exception {
        ossClient.shutdown();
    }
}
